package com.tqfframe.studydemo.mySocketRpc.core;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
import java.util.Properties;

/**
 * @Author: 唐祺峰
 * @Date: 2020/12/4 0004 9:37
 * @Version 1.0
 */
public class RpcClint  implements Clinet {
    final static String  RPC_SERVER_HOST="RPC_SERVER_HOST";
    final static String  RPC_SERVER_PORT="RPC_SERVER_PORT";
    @Override
    public Object getService(Class aClass) {
        return Proxy.newProxyInstance(aClass.getClassLoader(), new Class[]{aClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //读取配置文件
                Properties properties = new Properties();
                InputStream resourceAsStream = aClass.getClassLoader().getResourceAsStream("rpc/RpcConfig.properties");
                properties.load(resourceAsStream);
                String host = properties.getProperty(RPC_SERVER_HOST);
                Integer port =new Integer((String) properties.get(RPC_SERVER_PORT));
                //RPC注册过程
                Socket socket = new Socket(host, port);
                OutputStream in= socket.getOutputStream();
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(in);

                //告诉服务端调用的是哪个类
                objectOutputStream.writeObject(aClass.getName());
                //告诉服务端调用的是哪个方法
                objectOutputStream.writeObject(method.getName());
                //告诉服务端调用方法传入的参数
                objectOutputStream.writeObject(args);
                //告诉服务端调用方法的参数类型
                objectOutputStream.writeObject(method.getParameterTypes());

                //完成序列化，刷新
                objectOutputStream.flush();

                //接受服务端响应结果
                ObjectInputStream  returnObj=new ObjectInputStream(socket.getInputStream());
                Object o = returnObj.readObject();


                //关闭流
                objectOutputStream.close();
                returnObj.close();
                resourceAsStream.close();
                socket.close();
                return o;
            }
        });
    }
}